package com.cs.dingdingauto

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.cs.dingdingauto.DingDingHelper.isMultiWindow
import com.cs.dingdingauto.extent.ExternalActivityUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.*
import java.util.concurrent.TimeUnit

/**
 * @author liguandong
 * @data 2023/7/4
 *
 */
@SuppressLint("StaticFieldLeak")
object DingDingHelper {
    //target 高版本要在  <queries> 添加
    private val dingdingPkName = "com.alibaba.android.rimet"
    private val holderAppPkName = "com.cs.holderapp"
    private const val TAG = "lgd"
    var isStart = false; private set
    private lateinit var context: Context
    var isMultiWindow = true; private set
    var isNewLaunch = false; private set
    var isSkipWeekDay = false; private set
    var atWorkTime = 0L; private set  //24小时制，毫秒单位
    var atNoonTime = 0L; private set  //24小时制，毫秒单位
    var offWorkTime = 0L; private set //24小时制，毫秒单位
    var atWorkRandomMin = 20L; private set //分钟
    var offWorkRandomMin = 20L; private set //分钟
    val atWorkHours get() = TimeUnit.MILLISECONDS.toHours(atWorkTime)
    val atWorkMin get() = TimeUnit.MILLISECONDS.toMinutes(atWorkTime) % 60

    val atNoonHours get() = TimeUnit.MILLISECONDS.toHours(atNoonTime)
    val atNoonMin get() = TimeUnit.MILLISECONDS.toMinutes(atNoonTime) % 60

    val offWorkHours get() = TimeUnit.MILLISECONDS.toHours(offWorkTime)
    val offWorkMin get() = TimeUnit.MILLISECONDS.toMinutes(offWorkTime) % 60

    //中午调起
    val isAtNoonEnable = true
    //下班调起
    val isOffWorkEnable = false

    private var isInit = false
    fun init(context: Context) {
        if(isInit){
            return
        }
        isInit = true
        this.context = context.applicationContext
        val sp = context.getSharedPreferences("dingding", Context.MODE_PRIVATE)
        atWorkTime = sp.getLong("atWorkTime", TimeUnit.HOURS.toMillis(7) + TimeUnit.MINUTES.toMillis(30))
        atNoonTime = sp.getLong("atNoonTime", TimeUnit.HOURS.toMillis(13) + TimeUnit.MINUTES.toMillis(50))
        offWorkTime = sp.getLong("offWorkTime", TimeUnit.HOURS.toMillis(17) + TimeUnit.MINUTES.toMillis(0))
        atWorkRandomMin = sp.getLong("atWorkRandomMin",atWorkRandomMin)
        offWorkRandomMin = sp.getLong("offWorkRandomMin",offWorkRandomMin)
        isNewLaunch = sp.getBoolean("isNewLaunch",false)
        isMultiWindow = sp.getBoolean("isMultiWindow",true)
        isSkipWeekDay = sp.getBoolean("isSkipWeekDay",false)
//        prepareNextLaunch()
    }

    fun setNewLaunch(value:Boolean){
        isNewLaunch = value
        val sp = context.getSharedPreferences("dingding", Context.MODE_PRIVATE)
        sp.edit()
            .putBoolean("isNewLaunch", isNewLaunch)
            .apply()
    }
    fun setMultiWindow(value:Boolean){
        isMultiWindow = value
        val sp = context.getSharedPreferences("dingding", Context.MODE_PRIVATE)
        sp.edit()
            .putBoolean("isMultiWindow", isMultiWindow)
            .apply()
    }
    fun setSkipWeekday(value:Boolean){
        isSkipWeekDay = value
        val sp = context.getSharedPreferences("dingding", Context.MODE_PRIVATE)
        sp.edit()
            .putBoolean("isSkipWeekDay", isSkipWeekDay)
            .apply()
    }

    fun update(newAtWorkTime: Long,newNoonHours:Long, newOffWorkTime: Long,newAtWorkRandomMin:Long,newOffWorkRandomMin:Long) {
        atWorkTime = newAtWorkTime
        atNoonTime = newNoonHours
        offWorkTime = newOffWorkTime
        atWorkRandomMin = Math.max(0,newAtWorkRandomMin)
        offWorkRandomMin = Math.max(0,newOffWorkRandomMin)
        val sp = context.getSharedPreferences("dingding", Context.MODE_PRIVATE)
        sp.edit()
            .putLong("atWorkTime", atWorkTime)
            .putLong("atNoonTime", atNoonTime)
            .putLong("offWorkTime", offWorkTime)
            .putLong("atWorkRandomMin", atWorkRandomMin)
            .putLong("offWorkRandomMin", offWorkRandomMin)
            .apply()
        prepareNextLaunch()
    }

    fun launchApp(packName: String) {
        //        val intent = Intent(context,MainActivity::class.java)
        //        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        //        context.startActivity(intent)

        //        val name = "com.alibaba.android.rimet"
        if (isNewLaunch){
            val intent = Intent(context,MainActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            ExternalActivityUtil.startActivity(context,intent)
            return
        }
        when((Math.random() * 3).toInt()){
            1,2->{
                Log.i(TAG, "launchApp getLaunchIntentForPackage模式")
                val packageManager = context.packageManager
                val intent = packageManager.getLaunchIntentForPackage(packName)
                if (intent != null) {
                    context.startActivity(intent)
                } else {
                    Log.e(TAG, "launchApp ${packName}: faild")
                }
            }else->{
                 Log.i(TAG, "launchApp FLAG_ACTIVITY_NEW_TASK模式")
                val intent = Intent(context,MainActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                context.startActivity(intent)
            }
        }
    }

    fun  launchDingDing(){
        val packageManager = context.packageManager
        val intent = packageManager.getLaunchIntentForPackage(dingdingPkName)
        if (intent != null) {
            context.startActivity(intent)
        } else {
            Log.e(TAG, "launchApp ${dingdingPkName}: faild")
        }
    }

    fun  launchHolderApp(){
        val packageManager = context.packageManager
        val intent = packageManager.getLaunchIntentForPackage(holderAppPkName)
        if (intent != null) {
            context.startActivity(intent)
        } else {
            Log.e(TAG, "launchApp ${dingdingPkName}: faild")
        }
    }


    private val taskTag = "dingding"
    private val atWorkRangMin get() = atWorkRandomMin
    private val atWorkRangMax get() = atWorkRangMin + 10L
    private val offWorkRangMin get() = offWorkRandomMin
    private val offWorkRangMax get() = offWorkRangMin + 10L
    private val oneMin = TimeUnit.MINUTES.toMillis(1)
    fun prepareNextLaunch() {
        val curToday = Calendar.getInstance()
        val dayOfWeek = curToday.get(Calendar.DAY_OF_WEEK)
        val curTime = curToday.timeInMillis
        curToday.set(Calendar.HOUR_OF_DAY, 0)
        curToday.set(Calendar.MINUTE, 0)
        curToday.set(Calendar.SECOND, 0)
        val curTodayStartTime = curToday.timeInMillis
        val nextDayStartTime = when {
            isSkipWeekDay && dayOfWeek == Calendar.FRIDAY ->{
                curTodayStartTime + TimeUnit.DAYS.toMillis(3)
            }
            isSkipWeekDay && dayOfWeek == Calendar.SATURDAY ->{
                curTodayStartTime + TimeUnit.DAYS.toMillis(2)
            }
            else -> {
                curTodayStartTime + TimeUnit.DAYS.toMillis(1)
            }
        }
//        val nextDayStartTime = curTodayStartTime + TimeUnit.DAYS.toMillis(1)
        val randomDelayTime = oneMin  * (Math.random() * 5 + 3).toInt()
        val delayTime = when {
            curTime < curTodayStartTime + atWorkTime -> {
                val randomTime = TimeUnit.MINUTES.toMillis(((Math.random() * atWorkRangMin).toLong()))
                curTodayStartTime + atWorkTime - curTime + randomTime
            }
            curTime <= curTodayStartTime + atWorkTime + TimeUnit.MINUTES.toMillis(atWorkRangMin) -> {
                randomDelayTime
            }

            isAtNoonEnable && curTime < curTodayStartTime + atNoonTime -> {
                curTodayStartTime + atNoonTime - curTime + TimeUnit.MINUTES.toMillis((Math.random() * offWorkRangMin).toLong())
            }
            isAtNoonEnable && curTime <= curTodayStartTime + atNoonTime + TimeUnit.MINUTES.toMillis(offWorkRangMin) -> {
                randomDelayTime
            }
            isOffWorkEnable && curTime < curTodayStartTime + offWorkTime -> {
                curTodayStartTime + offWorkTime - curTime + TimeUnit.MINUTES.toMillis((Math.random() * offWorkRangMin).toLong())
            }
            isOffWorkEnable && curTime <= curTodayStartTime + offWorkTime + TimeUnit.MINUTES.toMillis(offWorkRangMin) -> {
                randomDelayTime
            }
            else -> {
                val randomTime = TimeUnit.MINUTES.toMillis((Math.random() * atWorkRangMin).toLong())
                nextDayStartTime + atWorkTime - curTime + randomTime
            }
        }
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = curTime + delayTime

        val m = calendar.get(Calendar.MONTH) + 1
        val d = calendar.get(Calendar.DATE);
        val	h = calendar.get(Calendar.HOUR_OF_DAY);
        val	mi = calendar.get(Calendar.MINUTE);

        GlobalScope.launch(Dispatchers.Main){
            Toast.makeText(context, "触发时间 ${m}月 ${d}日 ${h}时 ${mi} 分", Toast.LENGTH_LONG).show()
        }

        Log.i("lgd", "prepareNextLaunch: 下次触发时间 ${TimeUnit.MILLISECONDS.toSeconds(delayTime)}s ${TimeUnit.MILLISECONDS.toMinutes(delayTime)}m 或者 ${
            TimeUnit.MILLISECONDS.toHours(delayTime)
        }h")
        WorkManager.getInstance(context).cancelAllWorkByTag(taskTag)
        val dingdingRequest = OneTimeWorkRequestBuilder<DingDingWork>().addTag(taskTag) // Additional configuration
            .setInitialDelay(delayTime, TimeUnit.MILLISECONDS).build()
        WorkManager.getInstance(context).enqueue(dingdingRequest)

//        if(delayTime > TimeUnit.MINUTES.toMillis(5)){
////            if(!AppUtils.isTopActivity(context,context.packageName)){
//                Log.i("lgd", "延迟时间大于5分钟以上，先拉起自身")
//                //启动自身
//                val request = OneTimeWorkRequestBuilder<LaunchAppWork2>().addTag(taskTag).setInitialDelay(2,TimeUnit.SECONDS).build() // Additional configuration
//                WorkManager.getInstance(context).enqueue(request)
////            }
//
////            val request1 = OneTimeWorkRequestBuilder<LaunchAppWork2>().addTag(taskTag)
////                .setInitialDelay(delayTime, TimeUnit.MILLISECONDS).build() // Additional configuration
////            WorkManager.getInstance(context).enqueue(request1)
//        }
    }

    fun cancelTask(){
        WorkManager.getInstance(context).cancelAllWorkByTag(taskTag)
    }
}